package com.jt;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;

import java.net.UnknownHostException;

@Configuration//自定义配置序列化方式
public class RedisConfig {//RedisAutoConfiguration
    //1.定义Redis序列化，反序列化规范对象
    public RedisSerializer jsonSerializer(){
        Jackson2JsonRedisSerializer serializer =
                new Jackson2JsonRedisSerializer(Object.class);
        //2.创建ObjectMapper(由jackson api库提供)对象，基于此对象进行序列化和反序列化
        //2.1创建ObjectMapper对象
        ObjectMapper objectMapper = new ObjectMapper();
        //2.2设置对哪些方法规则进行
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
//        objectMapper.setDefaultPropertyInclusion(JsonInclude.Include.NON_NULL);
        objectMapper.setVisibility(PropertyAccessor.GETTER,//get方法
                JsonAutoDetect.Visibility.ANY);//ANY 表示任意方法访问修饰符
        //2.3激活序列化类型存储，对象序列化时还会将对象的类型存储到redis数据库
        //假如没有这个配置，redis存储数据时不存储类型，反序列化时会默认将其数据存储到map
        objectMapper.activateDefaultTyping(
                objectMapper.getPolymorphicTypeValidator(),
                ObjectMapper.DefaultTyping.NON_FINAL, //激活序列化类型存储
                JsonTypeInfo.As.PROPERTY //表示类型会出现以json对象属性的形式存储
        );
        serializer.setObjectMapper(objectMapper);
        return serializer;
    }

    @Bean
    public RedisTemplate<Object, Object> redisTemplate(
            RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
        RedisTemplate<Object, Object> template = new RedisTemplate();
        template.setConnectionFactory(redisConnectionFactory);

        template.setKeySerializer(RedisSerializer.string());
        template.setHashKeySerializer(RedisSerializer.string());
        template.setValueSerializer(jsonSerializer());
        template.setHashValueSerializer(jsonSerializer());
        return template;
    }
}